FIT2-2022b 第06回 オブジェクト
前回授業の復習
先週の成果物のミソ
①ボールを3個に増やす
https://gyazo.com/e0c44ebbd093e62404940fe0a33aa6d0
②ゲームオーバーを管理する
https://gyazo.com/1a6c598daa6419dedea97a633afcece8
①ボールを3個に増やす = 「リスト」の利用
https://gyazo.com/1f6158ef976ee924992a4a1e14def2c5
code:python
# ballx, ballyそれぞれに値を3つもたせる (各列が各ボールに対応)
speed = 1
# 1個目のボールのx,y座標は以下のように取り出せる
# 1個目が0 になる点に注意 (設計として最初の要素は0番目となる) pyxel.circ(ballx0, bally0, 10, 6) # 以下のようにfor文を利用して、ballx0, ballx1, ballx2 それぞれを順番に更新可能 for i in range(0, 3):
②ゲームオーバーを管理する
code:python
# 新しい変数を2つ用意する
failed = 0
isGameover = False
def update():
global ballx, bally ...(中略)... failed, isGameover
# (中略)
for i in range(0, len(ballx)):
# (中略)
# ボールがキャッチできずに画面下端に来た時にfailedを1増やす
failed = failed + 1
if failed >= 10:
# failedが10以上になったら isGameoverをTrueに変更
isGameover = True
# (中略)
def draw():
if isGameover:
# ゲームオーバー時の描画
# pyxel.cls(7) を実行しないことによってゲームオーバーになった瞬間の画面を維持
pyxel.text(50, 100, 'GAME OVER', 0)
else:
# 通常のゲーム画面描画はisGameoverがTrueになると以後実行されない
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 6) # 中略
最終形
code:python
import pyxel
pyxel.init(200,200)
speed = 1 # ボールの速度を管理
padx = 100 # padの中心座標
score = 0 # 点数
failed = 0 # キャッチ失敗回数
isGameover = False # ゲームオーバー判定
# ボールのxy座標、移動量を管理するリストを用意
ballx = []
bally = []
vx = []
vy = []
# for文を3回回して最初のぼーる3個を生成する
for i in range(0, 3):
# .append() はリストの末尾に値を追加する関数
ballx.append(pyxel.rndi(0, 199))
bally.append(0)
# 角度はボール毎にランダムに設定する
angle = pyxel.rndi(30,150)
vx.append(pyxel.cos(angle))
vy.append(pyxel.sin(angle))
def update():
global ballx, bally, vx, vy, padx, speed, score, failed, isGameover
# padの座標最新化は1回やればよい
padx = pyxel.mouse_x
# 全ballに対して移動・接触判定処理を行う
for i in range(0, len(ballx)): # len(ballx)は初期状態だと3を返すので iは0,1,2と繰り返される
# i番目のボールの移動処理
# i番目のボールが左右の壁に当たったら、x軸の移動方向を反転
if ballxi <= 0 or 200 <= ballxi: # i番目のボールの上下左右座標を取得 (正方形と仮定)
# padの上下左右位置を計算
pxl = padx - 20
pxr = padx + 20
pyt = 195
pyb = 200
# ボールの左右端がpadの左右幅に入っているかどうかを判定
if pxl <= bxr and bxl <= pxr:
# ボールの上下端がpadの上下幅に入っているかどうか
if pyt <= byb and byt <= pyb:
# キャッチ成功したのでスコアを増やす
score += 100
# 接触後すぐにボールを上に戻さないとスコアが増え続けるので位置を初期化
ballxi = pyxel.rndi(0,199) angle = pyxel.rndi(30,150)
elif ballyi >= 200: # キャッチに失敗した # 失敗回数をカウントアップ
failed = failed + 1
if failed >= 10:
# 10回に到達したらゲームオーバー
isGameover = True
# padに接触せずとも下辺に到達したらボールを上に戻す
ballxi = pyxel.rndi(0,199) angle = pyxel.rndi(30,150)
def draw():
global ballx, bally, padx, score, isGameover
if isGameover:
# ゲームオーバー時の描画
pyxel.text(50, 100, 'GAME OVER', 0)
else:
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 6) pyxel.rect(padx-20, 195, 40, 5, 14)
pyxel.text(0, 0, str(score), 0)
pyxel.run(update, draw)
本日の講義
https://gyazo.com/d8961914c1c72c0eb41eb0f9ceaa9c2a
リストの可読性の悪さを解決するための手段を伝えます
ボールの初期化処理
https://gyazo.com/c6091343ff6ab6afa938c44b78097771
Ballという概念はどのようなものかを定義 (class Ball)
Ballという概念はどのような処理を持つかを定義 (def move)
ボールの移動計算
https://gyazo.com/40240c2ab40ece28b98806e079763a4c
for文がわかりやすくなっている点にも要注目
余談
オブジェクト/メソッドがわかるとこんなに便利!
例えばシューティングゲームを作るとして…
code:python
class Enemy:
size = 3
color = 2
def __init__(self, x, y, vx, vy):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.hp = 100
def move(self):
self.x = self.x + self.vx
self.y = self.y + self.vy
def isDead(self):
return self.hp <= 0
def draw(self):
pyxel.rect(self.x, self.y, Enemy.size, Enemy.size, Enemy.color)
演習
Part1 B-12-2まで!
課題
B-11系統一式
必須は★★★まで (=今週は全部!)
企画書の提出も11/15期日です!
次回からはミニプロ解説へ
https://gyazo.com/2a9aae01a6337e8bfa054c151373757d
pyxel_examplesに入ってるjump_gameの解説で横スクロールを説明します
shootingも独自教材をお見せしましょう